#include "ChatPart.h"
#include "Player.h"
#include "PlayerMgr.h"
#include "Common/TableData/FunctionunlockFunctionUnlockCfg.h"

using namespace ProtoBuf;

ChatPart::ChatPart()
{
	freeTimes = 0;
	updateTime = 0;
	worldCdTime = 0;
	guildCdTime = 0;
	teamCdTime = 0;
	sceneCdTime = 0;
	campCdTime = 0;
}

ChatPart::~ChatPart()
{
}

bool ChatPart::SaveDB(CharacterDBInfo& characterDB)
{
	CharacterChatData* pChatData = characterDB.mutable_chatdata();
	pChatData->set_freetimes(freeTimes);
	pChatData->set_updatetime(updateTime);

	return true;
}

bool ChatPart::Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB /* = nullptr */)
{
	Part::Init(pMaster, partType);

	const CharacterChatData& chatData = pCharacterDB->chatdata();

	freeTimes = chatData.freetimes();
	updateTime = chatData.updatetime();

	return true;
}

bool ChatPart::UnInit()
{
	return true;
}

bool ChatPart::OnMsgHandle(uint32_t cmd, const char* data, uint32_t len)
{
	switch (cmd)
	{
	case CLIENT_TO_LOGIC_CHATMSGREQ:
		HandleChatMsgReq(data, len);
		break;
	default:
		break;
	}
	return true;
}

void ChatPart::HandleChatMsgReq(const char* data, uint32_t len)
{
	ProtoBuf::CGChatMsgReq c2gChatMsg;
	ProtoBuf::GCChatMsgRsp chatMsgRsp;

	if (!c2gChatMsg.ParseFromArray(data, len))
	{
		MMOLOG_FMT_ERROR("[logic] CGChatMsgReq parse failed...");
		return;
	}

	Player* pPlayer = dynamic_cast<Player*>(m_pMaster);
	if (nullptr == pPlayer)
	{
		MMOLOG_FMT_ERROR("[logic] ChatPart::HandleChatMsgReq but Player is nullptr");
		return;
	}

	CharIDType fromID = pPlayer->GetCid();
	CharIDType targetID = c2gChatMsg.targetid();

	//这里开始做消息转发
	bool bCanSay = true;

	ProtoBuf::CHAT_TYPE chatType = c2gChatMsg.chattype();

	switch (chatType)
	{
	case ProtoBuf::CHAT_TYPE_WORLD:
	{
		/*if (GetChatWorldFreeTime() <= 0)
		{
			Part *pPackage = pPlayer->GetPart(PART_PACKAGE);
			if (nullptr == pPackage)
			{
				chatMsgRsp.set_ret(RET_FAIL);
				pPlayer->SendDataToClient(EMODULE_ID_CHAT, ProtoBuf::LOGIC_TO_CLIENT_CHATMSGREQ, &chatMsgRsp);
				return;
			}

			int32_t unBindCount = 0;
			int32_t nBindCount = 0;
			int32_t count = pPackage->GetItemNum(CHAT_WORLD_USE_GOODS_ID, unBindCount, nBindCount);
			if (count <= 0)
			{
				chatMsgRsp.set_ret(RET_CHAT_FREE_GOODS_LIMIT);
				pPlayer->SendDataToClient(EMODULE_ID_CHAT, ProtoBuf::LOGIC_TO_CLIENT_CHATMSGREQ, &chatMsgRsp);
				return;
			}

			if (!InChannelCdTime(chatType))
			{
				chatMsgRsp.set_ret(RET_CHAT_CD_TIME_LIMIT);
				pPlayer->SendDataToClient(EMODULE_ID_CHAT, ProtoBuf::LOGIC_TO_CLIENT_CHATMSGREQ, &chatMsgRsp);
				return;
			}

			pPackage->RemoveItem(CHAT_WORLD_USE_GOODS_ID,1, S_Chat);
		}
		else*/
		{
			const FunctionunlockFunctionUnlockCfgInfo *pCfg = g_GetFunctionunlockFunctionUnlockCfgTable()->GetFunctionunlockFunctionUnlockCfgInfo(FunctionUnlock_ID_TYPE_WORLD_CHAT_LEVEL);
			if (nullptr != pCfg && pPlayer->GetAttr(C_LEVEL) < pCfg->unlockLevel)
			{
				chatMsgRsp.set_ret(RET_LEVEL_LACK);
				pPlayer->SendDataToClient(EMODULE_ID_CHAT, ProtoBuf::LOGIC_TO_CLIENT_CHATMSGREQ, &chatMsgRsp);
				return;
			}

			if (!InChannelCdTime(chatType))
			{
				chatMsgRsp.set_ret(RET_CHAT_CD_TIME_LIMIT);
				pPlayer->SendDataToClient(EMODULE_ID_CHAT, ProtoBuf::LOGIC_TO_CLIENT_CHATMSGREQ, &chatMsgRsp);
				return;
			}

			freeTimes++;
		}

		break;
	}
	case ProtoBuf::CHAT_TYPE_HORN:
	{
		Part *pPackage = pPlayer->GetPart(PART_PACKAGE);
		if (nullptr == pPackage)
		{
			chatMsgRsp.set_ret(RET_FAIL);
			pPlayer->SendDataToClient(EMODULE_ID_CHAT, ProtoBuf::LOGIC_TO_CLIENT_CHATMSGREQ, &chatMsgRsp);
			return;
		}

		int32_t unBindCount = 0;
		int32_t nBindCount = 0;
		int32_t count = pPackage->GetItemNum(CHAT_WORLD_USE_HORN_GOODS_ID, unBindCount, nBindCount);
		if (count <= 0)
		{
			//chatMsgRsp.set_ret(RET_CHAT_FREE_GOODS_LIMIT);
			chatMsgRsp.set_ret(RET_CHAT_BIG_HORN_LIMIT);
			pPlayer->SendDataToClient(EMODULE_ID_CHAT, ProtoBuf::LOGIC_TO_CLIENT_CHATMSGREQ, &chatMsgRsp);
			return;
		}
		SItemSourceParam sourceParam;
		sourceParam.source = S_Chat;
		pPackage->RemoveItem(CHAT_WORLD_USE_HORN_GOODS_ID, 1, sourceParam);
		break;
	}
	case ProtoBuf::CHAT_TYPE_CAMP:
	case ProtoBuf::CHAT_TYPE_GUILD:
	case ProtoBuf::CHAT_TYPE_TEAM:
	case ProtoBuf::CHAT_TYPE_SCENE:
	{
		if (!InChannelCdTime(chatType))
		{
			chatMsgRsp.set_ret(RET_CHAT_CD_TIME_LIMIT);
			pPlayer->SendDataToClient(EMODULE_ID_CHAT, ProtoBuf::LOGIC_TO_CLIENT_CHATMSGREQ, &chatMsgRsp);
			return;
		}
		break;
	}
	case ProtoBuf::CHAT_TYPE_SYSTEM:
		break;
	case ProtoBuf::CHAT_TYPE_ENLIST:
		break;
	default:
		break;
	}

	if (bCanSay)
	{
		ProtoBuf::GCChatMsgRsp a2cChatMsg; //直接发送给客户端
		ProtoBuf::GWChatMsgReq g2wChatMsg; //向中心服请求

		ProtoBuf::CharacterPlayerMiniInfo* playerMiniInfo = a2cChatMsg.mutable_fromplayerinfo();
		playerMiniInfo->set_playerid(pPlayer->GetCid());
		playerMiniInfo->set_playername(pPlayer->GetName());
		playerMiniInfo->set_sex(pPlayer->GetAttr(C_GENDER));
		playerMiniInfo->set_level(pPlayer->GetAttr(C_LEVEL));
		playerMiniInfo->set_prof(pPlayer->GetAttr(C_PROF));
		a2cChatMsg.set_chattype(chatType);
		a2cChatMsg.mutable_chatcontent()->CopyFrom(c2gChatMsg.chatcontent());
		a2cChatMsg.set_msgtype(c2gChatMsg.msgtype());

		g2wChatMsg.set_chattype(chatType);
		g2wChatMsg.set_msgtype(c2gChatMsg.msgtype());
		g2wChatMsg.mutable_chatcontent()->CopyFrom(c2gChatMsg.chatcontent());
		g2wChatMsg.set_fromid(fromID);
		g2wChatMsg.set_targetid(targetID);

		switch (chatType)
		{
		case ProtoBuf::CHAT_TYPE_WORLD: //世界频道
		{
			//世界聊天发言一次触发成就
			ChatWorldEvent chatWorldEvent;
			g_GetEvent()->FireExecute(EVENT_CHAT, pPlayer->GetCid(), pPlayer->CreatureKind(), (ChatWorldEvent*)&chatWorldEvent, sizeof(chatWorldEvent));
			g_GetLogicService()->SendDataToCenter(EMODULE_ID_CHAT, CENTER_SERVER_PROTOCOL_CHAT_REQ, &g2wChatMsg);
			break;
		}
		case ProtoBuf::CHAT_TYPE_HORN: //大喇叭
		case ProtoBuf::CHAT_TYPE_CAMP: //阵营频道
		case ProtoBuf::CHAT_TYPE_TEAM: //队伍频道
		case ProtoBuf::CHAT_TYPE_ENLIST: //组队招募的
		case ProtoBuf::CHAT_TYPE_ROOM_ENLIST: //房间招募
		case ProtoBuf::CHAT_TYPE_GUILD:
		{
			g_GetLogicService()->SendDataToCenter(EMODULE_ID_CHAT, CENTER_SERVER_PROTOCOL_CHAT_REQ, &g2wChatMsg);
			break;
		}
		case ProtoBuf::CHAT_TYPE_SCENE: //场景聊天
		{
			Scene* pScene = m_pMaster->GetScene();
			if (nullptr != pScene)
			{
				pScene->BroadCast2ClientInScene(EMODULE_ID_CHAT, LOGIC_TO_CLIENT_CHATMSGREQ, &a2cChatMsg);
			}
		}
			break;
		case ProtoBuf::CHAT_TYPE_SYSTEM:
			break;
		case ProtoBuf::CHAT_TYPE_PRIVATE: //私聊
		{
			g_GetLogicService()->SendDataToCenter(EMODULE_ID_CHAT,CENTER_SERVER_PROTOCOL_CHAT_REQ, &g2wChatMsg);
			break;
		}
		default:
			break;
		}
	}
}

uint32_t ChatPart::GetChatWorldFreeTime()
{
	uint32_t nowTime = (uint32_t)Time::Now().UnixSec();

	if (Time::GetLocalDayDifference(updateTime, nowTime))
	{
		freeTimes = 0;
		updateTime = nowTime;
		return CHAT_WORLD_FREE_TIMES;
	}

	return CHAT_WORLD_FREE_TIMES - freeTimes;
}

bool ChatPart::InChannelCdTime(ProtoBuf::CHAT_TYPE type)
{
	uint32_t nowTime = (uint32_t)Time::Now().UnixSec();
	if (type == CHAT_TYPE_WORLD)
	{
		if (nowTime - worldCdTime >= CHAT_WORLD_CD_TIME)
		{
			worldCdTime = nowTime;
			return true;
		}
	}
	else if (type == CHAT_TYPE_CAMP)
	{
		if (nowTime - campCdTime >= CHAT_OTHER_CD_TIME)
		{
			campCdTime = nowTime;
			return true;
		}
	}
	else if (type == CHAT_TYPE_GUILD)
	{
		if (nowTime - guildCdTime >= CHAT_OTHER_CD_TIME)
		{
			guildCdTime = nowTime;
			return true;
		}
	}
	else if (type == CHAT_TYPE_TEAM)
	{
		if (nowTime - teamCdTime >= CHAT_OTHER_CD_TIME)
		{
			teamCdTime = nowTime;
			return true;
		}
	}
	else if (type == CHAT_TYPE_SCENE)
	{
		if (nowTime - sceneCdTime >= CHAT_OTHER_CD_TIME)
		{
			sceneCdTime = nowTime;
			return true;
		}
	}

	return false;
}